package nz.ac.massey.cs.plot;

import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import nz.ac.massey.cs.stats.utils.Statistic;

public class Boxplot extends ScatterPlot {
    
	private Map<double[], Collection<Double>> grouped;
    
    public Boxplot() {
        this(new ArrayList<Double>(), new ArrayList<Double>());
    }

    public Boxplot(List<Double> xs, List<Double> ys) {
        super(xs, ys);
        this.grouped = new HashMap<double[], Collection<Double>>();
        this.setShowXGridLines(false);
        this.setShowYGridLines(false);
        this.setPlotColor(Color.BLACK);
        this.setIntervalColor(Color.BLACK);
        this.setXyLabelColor(Color.BLACK);
    }

    private void groupData(List<Double> xs, List<Double> ys) {
    	
    	double xWidth = (getXmax()-getXmin())/getXClasses();
    	for(double x=getXmin();x<getXmax();x+=xWidth){
    		grouped.put(new double[]{x,x+xWidth}, new ArrayList<Double>());
    	}
    	
        for (int i = 0; i < xs.size(); i++) {
            Double x = xs.get(i); //getXmin() + (double) (getxClasses() * ((int) (xs.get(i) / getxClasses())));
            Double y = ys.get(i);

            //grouped.get(x).add(y);
            for(double[] group : grouped.keySet()){
            	if(x>=group[0] && x<group[1]){
            		grouped.get(group).add(y);
            	}
            }
        }
       // System.out.println(grouped.size());
    }

    @Override
    public void drawXYPlots(Graphics2D g, List<Double> xs, List<Double> ys) {

        if (grouped.isEmpty()) groupData(xs, ys);
        
        //System.out.println(getxClasses());
        
        for (double[] X : grouped.keySet()) {
            Statistic statistic = Statistic.of(grouped.get(X));

            int x = (int) getScaledX((X[0]+X[1])/2);
            int ymin = (int) getScaledY(statistic.minWithoutOutliers);
            int ymax = (int) getScaledY(statistic.maxWithoutOutliers);
            int yQ1 = (int) getScaledY(statistic.Q1);
            int yQ2 = (int) getScaledY(statistic.median);
            int yQ3 = (int) getScaledY(statistic.Q3);


            g.setColor(getPlotColor());
            g.setStroke(getDashedStroke());
            g.drawLine(x + 2, ymin, x + 2, ymax);

            g.setStroke(getNormalStroke());
            g.drawLine(x, ymin + 1, x + 4, ymin + 1);
            g.drawLine(x, ymax - 1, x + 4, ymax - 1);

            g.setColor(Color.WHITE);
            g.drawLine(x + 2, yQ1, x + 2, yQ3);

            g.setColor(getPlotColor());
            g.drawPolygon(new int[]{x, x + 4, x + 4, x},
                    new int[]{yQ1, yQ1, yQ3, yQ3}, 4);

            g.drawLine(x, yQ2 - 1, x + 4, yQ2 - 1);
            g.drawLine(x, yQ2, x + 4, yQ2);
            g.drawLine(x, yQ2 + 1, x + 4, yQ2 + 1);

            for (double y : statistic.outliers) {
                g.drawOval(x, (int) getScaledY(y), 4, 3);
            }
        }

    }
}
